-- 用户数据

local ngx = ngx
local type = type
local pairs = pairs
local math_random = math.random
local table_insert = table.insert
local log       = require("modules.commhm.log");
local uu = require('modules.commhm.utils')
local setmetatable = setmetatable
local table = table
local tostring = tostring
local math_floor = math.floor
local string_format = string.format
local mis_config = nil
local mis_common = nil
local mis_log = nil
local mis_mysql = nil
local mis_data = nil
local mis_qps = nil
local mis_calcu = nil
local t_retCode = nil
local ma_ssdb = nil 		-- ma服的数据,用于拉取用户信息
local mis_ssdbDcClient = require('modules.commhm.dc.ssdbDcClient')
--------------------------------------------------------------
local mis_user = {
	s_name = string.match(debug.getinfo(1).short_src, '.*/(.*).lua');	-- 模块名称
--	n_uin = nil;
--	t_ssdb = nil;
--	n_black = nil;														-- 黑名单标记
--	t_giftData = nil; 													-- 礼包数据
--	t_giftConf = nil;													-- 礼包配置
--	t_biaoqian = nil;													-- 标签数据
--	t_backData = nil;													-- 回归数据
--	t_baokuData = nil;													-- 宝库数据
--	t_coopData = nil;													-- 协作数据
--	t_missionData = nil;												-- 任务数据
--  t_luckyData = nil; 													-- 幸运值数据
--	t_outmanData = nil;													-- 奥特曼数据
--  t_unauthData = nil;												    -- 未实名用户
--	t_specialItemData = nil;											-- 特殊道具数据
--	t_rotateData = nil;													-- 转盘数据
--	t_diversionData = nil;												-- 导流数据
--  t_shareCodeData	=nil;												-- 分享码拉新活动
--	t_twobackData = nil;												-- 二期回归数据
--	t_nationaldayData = nil;											-- 国庆数据
--	t_growthguardData = nil;											-- 成长守护
--	t_weekendGiftData = nil;											-- 周末好礼
--	t_relicImitateData = nil;											-- 国宝复刻
--	t_relicImitateMapData = nil;											-- 国宝复刻地图数据
--	t_concertData = nil;												-- 音乐节数据
--	t_concertCodeData = nil;											-- 音乐节密码数据
--  t_activityData = nil												-- 活跃数据
--	t_dailySignData = nil;													-- 每日签到数据
--	t_noviceTaskData = nil;													-- 新手任务数据
}
local this = mis_user
this.__index = this

--------------------------------------------------------------
-- 说明：给黑盒写数据
-- 参数: n_hash		用于哈希算出落地的dc
--		s_key		数据key
--		t_data 		数据
--		s_work 		业务标识
-- 返回：n			状态码
-- 		ts 			描述
local function set_data_to_box_hash(self, n_hash, s_key, t_data, s_work)
	mis_qps.mark('dc')
	local n_dbIndex = n_hash % #mis_config.t_ssdbDc.t_select
	local s_workKey = self.n_uin
	if s_work then
		s_workKey = s_workKey .. "_" .. s_work
	end
	if t_data ~= nil then
		if self.t_ssdb:private_check_set_key(n_dbIndex, s_workKey, s_key, t_data) then
			local s_data = mis_common.table_to_string(t_data)
			local s_ret = self.t_ssdb:save(n_dbIndex, s_workKey, s_key, s_data)
			if not s_ret then
				local s_err = 'ssdb save error'
				mis_log.error(s_err)
				return t_retCode.n_DB_ERR, s_err
			end
		else
			local s_err = 'ssdb check key failed'
			mis_log.error(s_err)
			return t_retCode.n_DB_ERR, s_err
		end
	else
		-- 删除
		local s_ret = self.t_ssdb:del(n_dbIndex, s_workKey, s_key)
		if not s_ret then
			local s_err = 'ssdb del error'
			mis_log.error(s_err)
			return t_retCode.n_DB_ERR, s_err
		end
	end
	return t_retCode.n_OK
end

--------------------------------------------------------------
-- 说明：从黑盒读数据
-- 参数: n_hash		用于哈希算出落地的dc
--      s_key		数据key
--		b_readOnly	是否只读
--		s_work 		业务标识
-- 返回：n			状态码
-- 		ts 			描述
local function get_data_from_box_hash(self, n_hash, s_key, b_readOnly, s_work)
	mis_qps.mark('dc')
	local n_dbIndex = n_hash % #mis_config.t_ssdbDc.t_select
	local s_workKey = self.n_uin
	if s_work then
		s_workKey = s_workKey .. "_" .. s_work
	end
	local s_data = self.t_ssdb:read(n_dbIndex, s_workKey, s_key, nil, nil, b_readOnly and 1 or nil)
	if not s_data then
		local s_err = 'ssdb error'
		mis_log.error(s_err)
		return t_retCode.n_DB_ERR, s_err
	elseif s_data == ngx.null then
		return t_retCode.n_NO_DATA, 'no data'
	else
		local t_data = mis_common.string_to_table(s_data)
		if type(t_data) == 'table' then
			if not self.t_ssdb:private_check_get_key(n_dbIndex, s_workKey, s_key, t_data) then
				self.t_ssdb:clean_shared_cache_ssdb(n_dbIndex, s_workKey, s_key)
				local s_err = 'user ssdb data has been damaged 1, uin=' .. self.n_uin .. ', key=' .. s_key .. ", work=" .. uu.to_str(s_work)
				mis_log.error(s_err)
				return t_retCode.n_DB_ERR, s_err
			end
		else
			local code, err = self.t_ssdb:clean_shared_cache_ssdb(n_dbIndex, s_workKey, s_key)
			local s_err = 'user ssdb data has been damaged 2, uin=' .. self.n_uin .. ', key=' .. s_key .. ", work=" .. uu.to_str(s_work) .. ", data=" .. s_data .. ", code=" .. uu.to_str(code) .. ", err=" .. uu.to_str(err)
			mis_log.error(s_err)
			return t_retCode.n_DB_ERR, s_err
		end
		return t_retCode.n_OK, t_data
	end
end

--------------------------------------------------------------
-- 说明：从黑盒读数据
-- 参数：s_key		数据key
--		b_readOnly	是否只读
-- 返回：n			状态码
-- 		ts 			描述
local function get_data_from_box(self, s_key, b_readOnly)
	return get_data_from_box_hash(self, self.n_uin, s_key, b_readOnly)
end

--------------------------------------------------------------
-- 说明：给黑盒写数据
-- 参数:s_key		数据key
--		t_data 		数据
-- 返回：n			状态码
-- 		ts 			描述
local function set_data_to_box(self, s_key, t_data)
	return set_data_to_box_hash(self, self.n_uin, s_key, t_data)
end

--------------------------------------------------------------
-- 说明：从黑盒读数据
-- 参数：s_key		数据key
--		b_readOnly	是否只读
-- 返回：n			状态码
-- 		ts 			描述
local function get_data_from_box_ma(self, s_key, b_readOnly)
	mis_qps.mark('dc')
	local n_dbIndex = self.n_uin % 10
	local s_data = ma_ssdb:read(n_dbIndex, self.n_uin, s_key, nil, nil, b_readOnly and 1 or nil)
	if not s_data then
		local s_err = 'ma_ssdb error'
		mis_log.error(s_err)
		return t_retCode.n_DB_ERR, s_err
	elseif s_data == ngx.null then
		return t_retCode.n_NO_DATA, 'no data'
	else
		local t_data = mis_common.string_to_table(s_data)
		if type(t_data) == 'table' then
			if not ma_ssdb:private_check_get_key(n_dbIndex, self.n_uin, s_key, t_data) then
				ma_ssdb:clean_shared_cache_ssdb(n_dbIndex, self.n_uin, s_key)
				local s_err = 'user ma_ssdb data has been damaged 1, uin=' .. self.n_uin .. ', key=' .. s_key
				mis_log.error(s_err)
				return t_retCode.n_DB_ERR, s_err
			end
		else
			ma_ssdb:clean_shared_cache_ssdb(n_dbIndex, self.n_uin, s_key)
			local s_err = 'user ma_ssdb data has been damaged 2, uin=' .. self.n_uin .. ', key=' .. s_key
			mis_log.error(s_err)
			return t_retCode.n_DB_ERR, s_err
		end
		return t_retCode.n_OK, t_data
	end
end

--------------------------------------------------------------
-- 说明：从黑盒批量读数据
-- 参数：s_key		数据key
--		b_readOnly	是否只读
-- 返回：n			状态码
-- 		ts 			描述
local function get_data_from_box_batch(self, kv_list)
	mis_qps.mark('dc')
	local n_dbIndex = self.n_uin % #mis_config.t_ssdbDc.t_select
	local ret_mread_ = self.t_ssdb:mread(n_dbIndex, kv_list, nil)
	local ret_list = {};

	for i=1, #ret_mread_ do
		local ret = ret_mread_[i];
		if  ret == ngx.null then
			table_insert( ret_list, { __key=kv_list[i].key, __hash = kv_list[i].hash, __nil = 1 } );
		else
			local ret_table_ = table.loadstring( ret );
			if  type(ret_table_) == 'table' then
			else
				mis_log.error( "loadstring to table error. str=" .. ret );
				return t_retCode.n_DB_ERR, ret;
			end

			ret_table_.__key = kv_list[i].key;
			ret_table_.__hash = kv_list[i].hash;
			table_insert( ret_list , ret_table_ );
		end
	end

	return t_retCode.n_OK, ret_list;
end

--------------------------------------------------------------
-- 说明：创建函数
-- 参数：n_uin
--		t_ssdb
--		t_lru
-- 返回：t		mis_user对象
this.new = function(n_uin, t_ssdb)
	local t_o = {
		n_uin = n_uin;
		t_ssdb = t_ssdb;
		b_lockMark = false;
	}
	setmetatable(t_o, this)
	return t_o
end

--------------------------------------------------------------
-- 说明：模块包含
-- 参数：模块表
this.modules_include = function(t_moddules)
	mis_config = t_moddules.mis_config
	mis_common = t_moddules.mis_common
	mis_log = t_moddules.mis_log
	mis_mysql = t_moddules.mis_mysql
	mis_data = t_moddules.mis_data
	mis_qps = t_moddules.mis_qps
	mis_calcu = t_moddules.mis_calcu
	t_retCode = mis_config.t_retCode
end

--------------------------------------------------------------
-- 说明：获得用户基础数据
-- 返回：n			状态码
--		ts 			描述
function this:get_user_basic()

	if  (not ma_ssdb) and mis_config.ma_ssdb_server_dc.server then
		ma_ssdb = mis_ssdbDcClient:new( "ma",mis_config.ma_ssdb_server_dc.server,mis_config.ma_ssdb_server_dc.select )
		
	end
	local ret,data

	if ma_ssdb == nil then --没有就继续读老的先
	--	mis_log.print("zhu_task_test","flag-1",self.n_uin)
		ret,data = get_data_from_box(self, mis_config.t_ssdbKey.s_USER, true)
	else
		ret,data = get_data_from_box_ma(self, mis_config.t_ssdbKey.s_USER, true)
		ma_ssdb:final()
	end

	if ret == t_retCode.n_OK then
		if data.last_login_time and data.afk_time then
			data.last_login_time = tonumber(data.last_login_time) - tonumber(data.afk_time)
			--mis_log.print("zhu_task_test","flag-2",self.n_uin,data.last_login_time,data.afk_time)
		end
	end

	return ret,data
end

--------------------------------------------------------------
-- 说明：获得玩家标签
-- 返回：n 			状态码
--		ts 			描述
function this:get_biaoqian()
	if not self.t_biaoqian and mis_config.t_mysql.t_biaoqian then
		local n_code, ts_res = mis_mysql.query_once(
						mis_config.t_mysql.t_biaoqian,
						'SELECT `last_login_60days`,`pay_money`,`create_at` FROM `' ..
						mis_config.t_mysql.t_biaoqian.s_table .. '` WHERE `uin`=' .. ngx.quote_sql_str(self.n_uin),
						self.n_uin .. 'biaoqian')
		if n_code == t_retCode.n_OK then
			if #ts_res > 0 then ts_res = ts_res[1] end
			self.t_biaoqian = ts_res
		else
			return n_code, ts_res
		end
	end
	return t_retCode.n_OK, self.t_biaoqian
end

--------------------------------------------------------------
-- 说明：是否是黑名单玩家
-- 返回：n			状态码
--		n 			0:否，1:是
function this:is_black()
	if not self.n_black and mis_config.t_mysql.t_black then
		local n_code, ts_res = mis_mysql.query_once(
						mis_config.t_mysql.t_black,
						'SELECT 1 FROM `' .. mis_config.t_mysql.t_black.s_table ..
						'` WHERE `uin`=' .. ngx.quote_sql_str(self.n_uin) .. ' LIMIT 1',
						self.n_uin .. 'black')
		if n_code == t_retCode.n_OK then
			self.n_black = #ts_res > 0 and 1 or 0
		else
			return n_code, ts_res
		end
	end
	return t_retCode.n_OK, self.n_black
end

--------------------------------------------------------------
-- 说明：获得未获赠生日蛋糕的未实名玩家[已修改为实名+未实名]
-- 返回：n 			状态码
--		ts 			描述
function this:get_unauth_data( n_count )
	if not self.t_unauthData and mis_config.t_mysql.t_unauth then
		local n_code, ts_res = mis_mysql.query_once(
				mis_config.t_mysql.t_unauth,
				'SELECT `uin`,`flag` FROM `' ..
						mis_config.t_mysql.t_unauth.s_table .. '` WHERE `uin`!=' .. ngx.quote_sql_str(self.n_uin) .. ' LIMIT ' .. n_count,
				self.n_uin .. 'birthday')
		if n_code == t_retCode.n_OK then
			self.t_unauthData = ts_res
		else
			return n_code, ts_res
		end
	end
	return t_retCode.n_OK, self.t_unauthData
end
--------------------------------------------------------------
-- 说明：校验玩家是否存在未实名数据表
-- 返回：n 			状态码
--		ts 			描述
function this:is_exist_unauth_user(n_unauth_uin)
	local n_code, ts_res = mis_mysql.query_once(
			mis_config.t_mysql.t_unauth,
			'SELECT `uin` FROM `' .. mis_config.t_mysql.t_unauth.s_table .. '` WHERE ' ..
					'`uin`=' .. ngx.quote_sql_str(n_unauth_uin))

	if n_code == t_retCode.n_OK and #ts_res > 0 then
		return true
	else
		return false
	end
end
--------------------------------------------------------------
-- 说明：更新未实名玩家领取蛋糕状态
-- 返回：n 			状态码
--		ts 			描述
function this:set_user_cake_status(n_unauth_uin)
	local n_code, ts_res = mis_mysql.query_once(
			mis_config.t_mysql.t_unauth,
			'UPDATE `' .. mis_config.t_mysql.t_unauth.s_table .. '` SET `flag`=1' .. ' WHERE `uin`=' ..
					ngx.quote_sql_str(n_unauth_uin))

	if n_code ~= t_retCode.n_OK then return n_code, ts_res end
	return t_retCode.n_OK
end
--------------------------------------------------------------
-- 说明：校验未实名玩家领取蛋糕状态备份表否已领取蛋糕
-- 返回：n 			状态码
--		ts 			描述
function this:auth_user_cake_status(n_unauth_uin)
	local n_code, ts_res = mis_mysql.query_once(
			mis_config.t_mysql.t_unauth_status,
			'SELECT `uin` FROM `' .. mis_config.t_mysql.t_unauth_status.s_table .. '` WHERE `flag`=1 and ' ..
					'`uin`=' .. ngx.quote_sql_str(n_unauth_uin))

	if n_code == t_retCode.n_OK and #ts_res > 0 then
		return true
	end
	return false
end
--------------------------------------------------------------
-- 说明：更新未实名玩家领取蛋糕状态备份表
-- 返回：n 			状态码
--		ts 			描述
function this:insert_user_cake_backup_status(n_unauth_uin, n_flag)
	return mis_mysql.query_once(
			mis_config.t_mysql.t_unauth_status,
			'INSERT INTO `' .. mis_config.t_mysql.t_unauth_status.s_table .. '`(`uin`, `flag`) VALUES(' ..
					n_unauth_uin .. ', \'' .. n_flag .. '\'' .. ')')
end

--------------------------------------------------------------
-- 说明：获得用户活跃数据
-- 返回：n 			状态码
--		ts 			描述
function this:get_activity_data()
	if not self.t_activityData and mis_config.t_mysql.t_user_activity then
		local n_code, ts_res = mis_mysql.query_once(
				mis_config.t_mysql.t_user_activity,
				'SELECT `uin`,`reg_date`,`last_30d_logins`,`is_adult`,`is_identified`,`last_login_date` FROM `' ..
						mis_config.t_mysql.t_user_activity.s_table .. '` WHERE `uin`=' .. ngx.quote_sql_str(self.n_uin) .. ' LIMIT 1',
				self.n_uin .. 'activity')
		if n_code == t_retCode.n_OK then
			for i = 1, #ts_res do
				ts_res[i].reg_date = mis_common.date_to_unix(ts_res[i].reg_date)
				ts_res[i].last_login_date = mis_common.date_to_unix(ts_res[i].last_login_date)
			end
			self.t_activityData = ts_res
		else
			return n_code, ts_res
		end
	end
	return t_retCode.n_OK, self.t_activityData
end
--------------------------------------------------------------
-- 说明：格式化特殊道具
-- 数据结构：{
--	[id] = num;
-- };
-- 返回：t					特殊道具数据
function this:new_specialItem_data()
	return {}
end

--------------------------------------------------------------
-- 说明：获得特殊道具数据
-- 参数：b_readOnly	是否只读
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:get_specialItem_data(b_readOnly, b_force)
	if not self.t_specialItemData or b_force then
		local n_code, ts_data = get_data_from_box(self, mis_config.t_ssdbKey.s_SPECIALITEM, b_readOnly)
		if n_code == t_retCode.n_NO_DATA then
			ts_data = {_v_ = mis_config.n_specialItemVer, [1] = self:new_specialItem_data()}
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_data
		end
		self.t_specialItemData = ts_data
	end
	-- 如果版本号不一致，清空数据
	if self.n_uin ~= 0 and self.t_specialItemData._v_ ~= mis_config.n_specialItemVer then
		self.t_specialItemData = {_v_ = mis_config.n_specialItemVer, [1] = self:new_specialItem_data()}
	end
	return t_retCode.n_OK, self.t_specialItemData[1]
end

--------------------------------------------------------------
-- 说明：设置特殊道具数据
-- 参数：t_data 		数据
-- 返回：n			状态码
--		s 			描述
function this:set_specialItem_data(t_data)
	if not self.t_specialItemData then
		self.t_specialItemData = {_v_ = mis_config.n_specialItemVer}
	end
	self.t_specialItemData[1] = t_data
	local n_code, s_desc = set_data_to_box(self, mis_config.t_ssdbKey.s_SPECIALITEM, self.t_specialItemData)
	self.t_specialItemData._k_ = nil
	self.t_specialItemData._t_ = nil
	return n_code, s_desc
end

--------------------------------------------------------------
-- 说明：删除特殊道具数据
-- 返回：n			状态码
--		s 			描述
function this:delete_specialItem_data()
	return set_data_to_box(self, mis_config.t_ssdbKey.s_SPECIALITEM, nil)
end

--------------------------------------------------------------
-- 说明：格式化礼包数据
-- 礼包数据结构：{
-- 	_v_ = 0;					版本号
-- 	{
-- 		[giftId] = {
-- 			status = 0;			状态(系统礼包使用字段)
-- 			count = 0;			购买次数统计(缺省代表无需统计购买次数)
-- 			freshTime = 0;		上次刷新时间戳(缺省代表无刷新)
-- 			nextTime = 0;		下次刷新时间戳(系统礼包使用字段)
-- 		};
-- }}
-- 返回：t			礼包数据
function this:new_gift_data()
	return {}
end


--------------------------------------------------------------
-- 说明：格式化礼包数据
-- 礼包数据结构：{
-- 	_v_ = 0;					版本号
-- 	{
--		todayPresentCount = 0;				当日赠送个数
--		lastPresentTime = 0;				上次赠送时间
-- 		todayPresentedUser = {				当日被赠送玩家
-- 			[uin] = {
--				presentedTimes = 0;			当日赠送次数
--			}
-- 		};
-- }}
-- 返回：t			礼包数据
function this:new_gift_data2()
	return {}
end

--------------------------------------------------------------
-- 说明：获得礼包数据
-- 参数：b_readOnly	是否只读
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:get_gift_data(b_readOnly, b_force)
	if not self.t_giftData or b_force then
		local n_code, ts_data = get_data_from_box(self, mis_config.t_ssdbKey.s_GIFT, b_readOnly)
		if n_code == t_retCode.n_NO_DATA then
			ts_data = {_v_ = mis_config.n_giftVer, [1] = self:new_gift_data(), [2] = self:new_gift_data2()}
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_data
		end
		self.t_giftData = ts_data
	end
	-- 如果版本号不一致，清空数据
	if self.n_uin ~= 0 and self.t_giftData._v_ ~= mis_config.n_giftVer then
		self.t_giftData = {_v_ = mis_config.n_giftVer, [1] = self:new_gift_data(), [2] = self:new_gift_data2()}
	end
	return t_retCode.n_OK, self.t_giftData[1], self.t_giftData[2]
end

--------------------------------------------------------------
-- 说明：设置礼包数据
-- 参数：t_data 		数据
-- 参数：t_data2 	数据
-- 返回：n			状态码
--		s 			描述
function this:set_gift_data(t_data, t_data2)
	if not self.t_giftData then
		self.t_giftData = {_v_ = mis_config.n_giftVer}
	end
	self.t_giftData[1] = t_data
	self.t_giftData[2] = t_data2
	local n_code, s_desc = set_data_to_box(self, mis_config.t_ssdbKey.s_GIFT, self.t_giftData)
	self.t_giftData._k_ = nil
	self.t_giftData._t_ = nil
	return n_code, s_desc
end

--------------------------------------------------------------
-- 说明：获得礼包配置
-- 参数：b_readOnly	是否只读
-- 返回：n			状态码
--		ts 			描述
function this:get_gift_conf(b_readOnly)
	if not self.t_giftConf then
		local n_code, ts_conf = get_data_from_box(self, mis_config.t_ssdbKey.s_GIFT_CONF, b_readOnly)
		if n_code == t_retCode.n_NO_DATA then
			ts_conf = {}
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_conf
		end
		ts_conf._k_ = nil
		ts_conf._t_ = nil
		self.t_giftConf = ts_conf
	end
	return t_retCode.n_OK, self.t_giftConf
end

--------------------------------------------------------------
-- 说明：设置礼包配置
-- 参数：t_conf 		配置
-- 返回：n			状态码
--		ts 			描述
function this:set_gift_conf(t_conf)
	local n_code, s_desc = set_data_to_box(self, mis_config.t_ssdbKey.s_GIFT_CONF, t_conf)
	t_conf._k_ = nil
	t_conf._t_ = nil
	self.t_giftConf = t_conf
	return n_code, s_desc
end

--------------------------------------------------------------
-- 说明：删除礼包数据
-- 返回：n			状态码
--		s 			描述
function this:delete_gift_data()
	return set_data_to_box(self, mis_config.t_ssdbKey.s_GIFT, nil)
end

--------------------------------------------------------------
-- 说明：格式化回归数据
-- 回归数据结构：{
--	status = 0;				回归状态
-- 	startTime = 0;			激活时间
-- 	loginTime = 0;			登录时间
-- 	black = 0;				是否黑名单
--	score = 0;				当前积分
--	totalScore = 0;			累计积分
--	email = 0;				是否已发送奖励邮件
--	progress = {			进度条已兑奖励表
--		[Id] = 0;			物品Id
--		...
--	};
--	bonus = {
--		[Id] = {
--			num = 0;		兑换次数
--		};
--		...
-- 	};
--	mission = {				任务表
--		[Id] = {
--			idx = 0;		序号
--			value = 0;		进度值
--			status = 0;		状态 1:待领取，2:已领取
-- 		};
--		...
-- 	};
--	missionEvent = {		按事件分类任务表
--		[eventId] = {		事件Id
--			[missionId] = mission[missionId];
--		};
--	};
--	record = {				兑换记录
--		{
--			itemId_price_num_time;
--			...
-- 		};
-- 	};
-- }
-- 参数：t_data		回归数据(缺省则新建数据)
-- 返回：t			回归数据
function this:new_back_data(t_data)
	t_data = t_data or {}
	t_data.status = mis_config.t_backStatus.n_INIT
	t_data.startTime = nil
	t_data.score = nil
	t_data.totalScore = nil
	t_data.email = nil
	t_data.progress = nil
	t_data.bonus = nil
	t_data.mission = {}
	t_data.missionEvent = {}
	t_data.record = nil
	for n_, t_ in pairs(mis_data.t_back.t_conf.t_mission) do
		local n_idx = nil
		if t_.n_stepType then
			if t_.n_stepType == mis_config.t_backStepType.n_ORDER then
				n_idx = 1
			elseif t_.n_stepType == mis_config.t_backStepType.n_RANDOM then
				n_idx = math_random(1, #t_)
			end
		end
		t_data.mission[n_] = {idx = n_idx}
		t_data.missionEvent[t_.n_event] = t_data.missionEvent[t_.n_event] or {}
		t_data.missionEvent[t_.n_event][n_] = t_data.mission[n_]
	end
	return t_data
end

--------------------------------------------------------------
-- 说明：获得回归数据
-- 参数：b_readOnly	是否只读
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:get_back_data(b_readOnly, b_force)
	if not self.t_backData or b_force then
		local n_code, ts_data = get_data_from_box(self, mis_config.t_ssdbKey.s_BACK, b_readOnly)
		if n_code == t_retCode.n_NO_DATA then
			ts_data = {_v_ = mis_config.n_backVer, [1] = self:new_back_data()}
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_data
		end
		self.t_backData = ts_data
	end
	-- 如果版本号不一致，清空数据
	if self.n_uin ~= 0 and self.t_backData._v_ ~= mis_config.n_backVer then
		self.t_backData = {_v_ = mis_config.n_backVer, [1] = self:new_back_data()}
	end
	return t_retCode.n_OK, self.t_backData[1]
end

--------------------------------------------------------------
-- 说明：设置回归数据
-- 参数：t_data 		数据
-- 返回：n			状态码
--		s 			描述
function this:set_back_data(t_data)
	if not self.t_backData then
		self.t_backData = {_v_ = mis_config.n_backVer}
	end
	self.t_backData[1] = t_data
	local n_code, s_desc = set_data_to_box(self, mis_config.t_ssdbKey.s_BACK, self.t_backData)
	self.t_backData._k_ = nil
	self.t_backData._t_ = nil
	return n_code, s_desc
end

--------------------------------------------------------------
-- 说明：删除回归数据
-- 返回：n			状态码
--		s 			描述
function this:delete_back_data()
	return set_data_to_box(self, mis_config.t_ssdbKey.s_BACK, nil)
end

--------------------------------------------------------------
-- 说明：格式化宝库数据
-- 宝库数据结构：{
--	[baokuId] = {
--		count = {
--			[goodId] = num;
--			...
--		};
--		coin = num;
--		record = {
--			itemId_num_cost_time;
--			...
--		};
--	};
-- }
-- 返回：t			宝库数据
function this:new_baoku_data()
	return {}
end

--------------------------------------------------------------
-- 说明：获得宝库
-- 参数：b_readOnly	是否只读
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:get_baoku_data(b_readOnly, b_force)
	if not self.t_baokuData or b_force then
		local n_code, ts_data = get_data_from_box(self, mis_config.t_ssdbKey.s_BAOKU, b_readOnly)
		if n_code == t_retCode.n_NO_DATA then
			ts_data = {_v_ = mis_config.n_baokuVer, [1] = self:new_baoku_data()}
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_data
		end
		self.t_baokuData = ts_data
	end
	-- 如果版本号不一致，清空数据
	if self.n_uin ~= 0 and self.t_baokuData._v_ ~= mis_config.n_baokuVer then
		self.t_baokuData = {_v_ = mis_config.n_baokuVer, [1] = self:new_baoku_data()}
	end
	return t_retCode.n_OK, self.t_baokuData[1]
end

--------------------------------------------------------------
-- 说明：设置宝库数据
-- 参数：t_data 		数据
-- 返回：n			状态码
--		s 			描述
function this:set_baoku_data(t_data)
	if not self.t_baokuData then
		self.t_baokuData = {_v_ = mis_config.n_baokuVer}
	end
	self.t_baokuData[1] = t_data
	local n_code, s_desc = set_data_to_box(self, mis_config.t_ssdbKey.s_BAOKU, self.t_baokuData)
	self.t_baokuData._k_ = nil
	self.t_baokuData._t_ = nil
	return n_code, s_desc
end

--------------------------------------------------------------
-- 说明：删除宝库数据
-- 返回：n			状态码
--		s 			描述
function this:delete_baoku_data()
	return set_data_to_box(self, mis_config.t_ssdbKey.s_BAOKU, nil)
end

--------------------------------------------------------------
-- 说明：格式化协作数据
-- 协作数据结构：{
--	[coopId] = {
--		status = num;			活动状态
--		time = num;				上次拉取状态的时间
--		apply = {				被申请列表
--			{uin=num,msg=string}玩家/留言
-- 		};
--		applyHash = {			被申请哈希表
--			[uin] = pos;
--		};
--		toApply = {				申请列表
--			num, num;
--		};
--		toApplyHash = {			申请哈希表
--			[uin] = pos
--		};
--		toApplyHead = num;		申请列表头部
--		score = num;
--		coworker = num;			队友
--		mission = {				任务列表
--			[missionId] = {
--				value = num;	进度值
--				status = num;	状态
--			};
-- 		};
--		bonus = {				已经获得的奖励id
--			id, id, ...;
--		}
-- 	};
-- }
-- 返回：t			协作数据
function this:new_coop_data()
	return {}
end

--------------------------------------------------------------
-- 说明：获得协作数据
-- 参数：n_id		活动id
--		b_readOnly	是否只读
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:get_coop_data(n_id, b_readOnly, b_force)
	if not self.t_coopData or b_force then
		local n_code, ts_data = get_data_from_box(self, mis_config.t_ssdbKey.s_COOP, b_readOnly)
		if n_code == t_retCode.n_NO_DATA then
			ts_data = {_v_ = mis_config.n_coopVer, [1] = self:new_coop_data()}
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_data
		end
		self.t_coopData = ts_data
	end
	-- 如果版本号不一致，清空数据
	if self.n_uin ~= 0 and self.t_coopData._v_ ~= mis_config.n_coopVer then
		self.t_coopData = {_v_ = mis_config.n_coopVer, [1] = self:new_coop_data()}
	end
	if n_id and not self.t_coopData[1][n_id] then
		self.t_coopData[1][n_id] = {status = mis_config.t_coopStatus.n_UNBIND}
	end
	return t_retCode.n_OK, self.t_coopData[1]
end

--------------------------------------------------------------
-- 说明：设置协作数据
-- 参数：t_data 		数据
-- 返回：n			状态码
--		s 			描述
function this:set_coop_data(t_data)
	if not self.t_coopData then
		self.t_coopData = {_v_ = mis_config.n_coopVer}
	end
	self.t_coopData[1] = t_data
	local n_code, s_desc = set_data_to_box(self, mis_config.t_ssdbKey.s_COOP, self.t_coopData)
	self.t_coopData._k_ = nil
	self.t_coopData._t_ = nil
	return n_code, s_desc
end

--------------------------------------------------------------
-- 说明：删除协作数据
-- 返回：n			状态码
--		s 			描述
function this:delete_coop_data()
	return set_data_to_box(self, mis_config.t_ssdbKey.s_COOP, nil)
end

--------------------------------------------------------------
-- 说明：格式化任务数据
-- 任务数据结构：{
-- loginTime = 0					登录时间
-- md5 = 0							配置md5
-- label = {
--		[labelId] = {
--			status = 1
--			activateTime = 0;		激活时间
--			task = {
--				[taskId] = {
--					activateTime = 0;激活时间
--					value = 0;		进度值
--					target = 0;		目标值
--					status = 0;		状态
--					bonusId = 0;	选择奖励id
--				};
--			};
--			random = 0;				随机次数
--			done = 0;				完成任务数
--			finish = 0;				领取奖励数
--			preId = 0;				上一次随机的id
--		};
-- 	};
--	taskEvent = {					按事件分类任务表
--		[eventId] = {
--			[labelId_taskId] = 1;
--		};
--	}};
-- 返回：t					任务数据
function this:new_mission_data()
	return {}
end

--------------------------------------------------------------
-- 说明：获得任务数据
-- 参数：b_readOnly	是否只读
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:get_mission_data(b_readOnly, b_force)
	if not self.t_missionData or b_force then
		local n_code, ts_data = get_data_from_box(self, mis_config.t_ssdbKey.s_MISSION, b_readOnly)
		if n_code == t_retCode.n_NO_DATA then
			ts_data = {_v_ = mis_config.n_missionVer, [1] = self:new_mission_data()}
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_data
		end
		self.t_missionData = ts_data
	end
	-- 如果版本号不一致，清空数据
	if self.n_uin ~= 0 and self.t_missionData._v_ ~= mis_config.n_missionVer then
		self.t_missionData = {_v_ = mis_config.n_missionVer, [1] = self:new_mission_data()}
	end
	return t_retCode.n_OK, self.t_missionData[1]
end

--------------------------------------------------------------
-- 说明：设置任务数据
-- 参数：t_data 		数据
-- 返回：n			状态码
--		s 			描述
function this:set_mission_data(t_data)
	if not self.t_missionData then
		self.t_missionData = {_v_ = mis_config.n_missionVer}
	end
	self.t_missionData[1] = t_data
	local n_code, s_desc = set_data_to_box(self, mis_config.t_ssdbKey.s_MISSION, self.t_missionData)
	self.t_missionData._k_ = nil
	self.t_missionData._t_ = nil
	return n_code, s_desc
end

--------------------------------------------------------------
-- 说明：删除任务数据
-- 返回：n			状态码
--		s 			描述
function this:delete_mission_data()
	return set_data_to_box(self, mis_config.t_ssdbKey.s_MISSION, nil)
end


--------------------------------------------------------------
-- 说明：格式化分享码数据
-- 分享码数据结构：{
--	[shareId] = {
--		time = num;				上次拉取状态的时间
--		share_uin_list = {		分享玩家列表
--			num, num;
-- 		};
--		score = num;			积分
--		bonus = {				已经获得的奖励id
--			id, id, ...;
--		}
-- 	};
-- }
-- 返回：t			分享码数据
function this:new_share_data()
	return {}
end
--------------------------------------------------------------
-- 说明：获得分享码活动数据
-- 参数：n_id		活动id
--		b_readOnly	是否只读
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:get_share_data(n_id, b_readOnly, b_force)
	if not self.t_shareCodeData or b_force then
		local n_code, ts_data = get_data_from_box(self, mis_config.t_ssdbKey.s_SHARE_CODE, b_readOnly)
		if n_code == t_retCode.n_NO_DATA then
			ts_data = {_v_ = mis_config.n_shareVer, [1] = self:new_share_data()}
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_data
		end
		self.t_shareCodeData = ts_data
	end
	-- 如果版本号不一致，清空数据
	if self.n_uin ~= 0 and self.t_shareCodeData._v_ ~= mis_config.n_shareVer then
		self.t_shareCodeData = {_v_ = mis_config.n_shareVer, [1] = self:new_share_data()}
	end
	if n_id and not self.t_shareCodeData[1][n_id] then
		self.t_shareCodeData[1][n_id] = {}
	end
	return t_retCode.n_OK, self.t_shareCodeData[1]
end

--------------------------------------------------------------
-- 说明：设置分享码数据
-- 参数：t_data 		数据
-- 返回：n			状态码
--		s 			描述
function this:set_share_data(t_data)
	if not self.t_shareCodeData then
		self.t_shareCodeData = {_v_ = mis_config.n_shareVer}
	end
	self.t_shareCodeData[1] = t_data
	local n_code, s_desc = set_data_to_box(self, mis_config.t_ssdbKey.s_SHARE_CODE, self.t_shareCodeData)
	self.t_shareCodeData._k_ = nil
	self.t_shareCodeData._t_ = nil
	return n_code, s_desc
end

--------------------------------------------------------------
-- 说明：删除分享码数据
-- 返回：n			状态码
--		s 			描述
function this:delete_share_data()
	return set_data_to_box(self, mis_config.t_ssdbKey.s_SHARE_CODE, nil)
end


--------------------------------------------------------------
-- 说明：创建幸运值数据
-- 数据结构
--	{
-- 		key_1 = box_id, value_1 = lucky_val;
--		key_2 = box_id, value_2 = lucky_val;
-- 		...
--	}
-- 返回：t					幸运值数据
function this:new_lucky_data()
	return {}
end
--------------------------------------------------------------
-- 说明：获取幸运值数据
-- 参数：b_readOnly	是否只读 一般为是
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:get_lucky_val_data(b_readOnly, b_force)
	if not self.t_luckyData or b_force then
		local n_code, ts_data = get_data_from_box(self, mis_config.t_ssdbKey.s_LUCKY, b_readOnly)
		if n_code == t_retCode.n_NO_DATA then
			ts_data = self:new_lucky_data()
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_data
		end

		self.t_luckyData = ts_data
	end

	return t_retCode.n_OK, self.t_luckyData
end
--------------------------------------------------------------
-- 说明：设置幸运值数据
-- 参数：t_data 		数据
-- 返回：n			状态码
--		s 			描述
function this:set_lucky_data(t_data)
	if not self.t_luckyData then
		self.t_luckyData = t_data
	end

	local n_code, s_desc = set_data_to_box(self, mis_config.t_ssdbKey.s_LUCKY, self.t_luckyData)
	return n_code, s_desc
end

--------------------------------------------------------------
-- 说明：格式化奥特曼数据
-- 奥特曼数据结构：{
--	[id] = {
--		time = 0;
--		rank = 0;
--	}};
-- 返回：t					奥特曼数据
function this:new_outman_data()
	return {}
end

--------------------------------------------------------------
-- 说明：获得奥特曼数据
-- 参数：b_readOnly	是否只读
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:get_outman_data(b_readOnly, b_force)
	if not self.t_outmanData or b_force then
		local n_code, ts_data = get_data_from_box(self, mis_config.t_ssdbKey.s_OUTMAN, b_readOnly)
		if n_code == t_retCode.n_NO_DATA then
			ts_data = {_v_ = mis_config.n_outmanVer, [1] = self:new_outman_data()}
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_data
		end
		self.t_outmanData = ts_data
	end
	-- 如果版本号不一致，清空数据
	if self.n_uin ~= 0 and self.t_outmanData._v_ ~= mis_config.n_outmanVer then
		self.t_outmanData = {_v_ = mis_config.n_outmanVer, [1] = self:new_outman_data()}
	end
	return t_retCode.n_OK, self.t_outmanData[1]
end

--------------------------------------------------------------
-- 说明：设置奥特曼数据
-- 参数：t_data 		数据
-- 返回：n			状态码
--		s 			描述
function this:set_outman_data(t_data)
	if not self.t_outmanData then
		self.t_outmanData = {_v_ = mis_config.n_outmanVer}
	end
	self.t_outmanData[1] = t_data
	local n_code, s_desc = set_data_to_box(self, mis_config.t_ssdbKey.s_OUTMAN, self.t_outmanData)
	self.t_outmanData._k_ = nil
	self.t_outmanData._t_ = nil
	return n_code, s_desc
end

--------------------------------------------------------------
-- 说明：删除奥特曼数据
-- 返回：n			状态码
--		s 			描述
function this:delete_outman_data()
	return set_data_to_box(self, mis_config.t_ssdbKey.s_OUTMAN, nil)
end

--------------------------------------------------------------
-- 说明：格式化生日数据
-- 生日数据结构：{
-- 	_v_ = 0;					版本号
-- 	{
-- 		[birthdayId] = {
-- 			birthday = 1230;				生日（12月30日）
-- 			constellation = ‘’;				星座
--			attire = 0;						参加派对四季装扮
--			avatar = 0;						生日礼物--头像框
-- 			cake_list = {[1]=10, [2]=10};	生日蛋糕赠送份额
-- 			cake_friend = {[1]={}, [2]={};	赠送好友蛋糕列表
--			gift = {[1]={}, [2]={}};		每年生日礼物列表
-- 		};
-- }}
-- 返回：t			生日数据
function this:new_birthday_data()
	return {}
end

--------------------------------------------------------------
-- 说明：获得礼包数据
-- 参数：b_readOnly	是否只读
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:get_birthday_data(b_readOnly, b_force)
	if not self.t_birthdayData or b_force then
		local n_code, ts_data = get_data_from_box(self, mis_config.t_ssdbKey.s_BIRTHDAY, b_readOnly)
		if n_code == t_retCode.n_NO_DATA then
			ts_data = {_v_ = mis_config.n_birthdayVer, [1] = self:new_birthday_data()}
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_data
		end
		self.t_birthdayData = ts_data
	end
	-- 如果版本号不一致，清空数据
	if self.n_uin ~= 0 and self.t_birthdayData._v_ ~= mis_config.n_birthdayVer then
		self.t_birthdayData = {_v_ = mis_config.n_birthdayVer, [1] = self:new_birthday_data()}
	end
	return t_retCode.n_OK, self.t_birthdayData[1]
end

--------------------------------------------------------------
-- 说明：设置礼包数据
-- 参数：t_data 		数据
-- 参数：t_data2 	数据
-- 返回：n			状态码
--		s 			描述
function this:set_birthday_data(t_data)
	if not self.t_birthdayData then
		self.t_birthdayData = {_v_ = mis_config.n_birthdayVer}
	end
	self.t_birthdayData[1] = t_data
	local n_code, s_desc = set_data_to_box(self, mis_config.t_ssdbKey.s_BIRTHDAY, self.t_birthdayData)
	self.t_birthdayData._k_ = nil
	self.t_birthdayData._t_ = nil
	return n_code, s_desc
end

--------------------------------------------------------------
-- 说明：获得礼包配置
-- 参数：b_readOnly	是否只读
-- 返回：n			状态码
--		ts 			描述
function this:get_birthday_conf(b_readOnly)
	if not self.t_birthdayConf then
		local n_code, ts_conf = get_data_from_box(self, mis_config.t_ssdbKey.s_BIRTHDAY_CONF, b_readOnly)
		if n_code == t_retCode.n_NO_DATA then
			ts_conf = {}
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_conf
		end
		ts_conf._k_ = nil
		ts_conf._t_ = nil
		self.t_birthdayConf = ts_conf
	end
	return t_retCode.n_OK, self.t_birthdayConf
end

--------------------------------------------------------------
-- 说明：设置礼包配置
-- 参数：t_conf 		配置
-- 返回：n			状态码
--		ts 			描述
function this:set_birthday_conf(t_conf)
	local n_code, s_desc = set_data_to_box(self, mis_config.t_ssdbKey.s_BIRTHDAY_CONF, t_conf)
	t_conf._k_ = nil
	t_conf._t_ = nil
	self.t_birthdayConf = t_conf
	return n_code, s_desc
end

--------------------------------------------------------------
-- 说明：删除礼包数据
-- 返回：n			状态码
--		s 			描述
function this:delete_birthday_data()
	return set_data_to_box(self, mis_config.t_ssdbKey.s_BIRTHDAY, nil)
end

--------------------------------------------------------------
-- 说明：格式化转盘数据
-- 数据结构：{
--	num = 0; 			抽奖次数
--	activateTime = 0;	活动激活时间
--	coin = 0;			抽到迷你币次数
-- };
-- 返回：t			转盘数据
function this:new_rotate_data()
	return {}
end

--------------------------------------------------------------
-- 说明：获得转盘数据
-- 参数：b_readOnly	是否只读
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:get_rotate_data(b_readOnly, b_force)
	if not self.t_rotateData or b_force then
		local n_code, ts_data = get_data_from_box(self, mis_config.t_ssdbKey.s_ROTATE, b_readOnly)
		if n_code == t_retCode.n_NO_DATA then
			ts_data = {_v_ = mis_config.n_rotateVer, [1] = self:new_rotate_data()}
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_data
		end
		self.t_rotateData = ts_data
	end
	-- 如果版本号不一致，清空数据
	if self.n_uin ~= 0 and self.t_rotateData._v_ ~= mis_config.n_rotateVer then
		self.t_rotateData = {_v_ = mis_config.n_rotateVer, [1] = self:new_rotate_data()}
	end
	return t_retCode.n_OK, self.t_rotateData[1]
end

--------------------------------------------------------------
-- 说明：设置转盘数据
-- 参数：t_data 		数据
-- 返回：n			状态码
--		s 			描述
function this:set_rotate_data(t_data)
	if not self.t_rotateData then
		self.t_rotateData = {_v_ = mis_config.n_rotateVer}
	end
	self.t_rotateData[1] = t_data
	local n_code, s_desc = set_data_to_box(self, mis_config.t_ssdbKey.s_ROTATE, self.t_rotateData)
	self.t_rotateData._k_ = nil
	self.t_rotateData._t_ = nil
	return n_code, s_desc
end

--------------------------------------------------------------
-- 说明：删除转盘数据
-- 返回：n			状态码
--		s 			描述
function this:delete_rotate_data()
	return set_data_to_box(self, mis_config.t_ssdbKey.s_ROTATE, nil)
end

--------------------------------------------------------------
-- 说明：获得导流数据
-- 参数：b_readOnly	是否只读
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:get_diversion_data(b_readOnly, b_force)
	if not self.t_diversionData or b_force then
		local n_code, ts_data = get_data_from_box(self, mis_config.t_ssdbKey.s_DIVERSION, b_readOnly)
		if n_code == t_retCode.n_NO_DATA then
			ts_data = {_v_ = mis_config.n_diversionVer, [1] = {}}
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_data
		end
		self.t_diversionData = ts_data
	end
	-- 如果版本号不一致，清空数据
	if self.n_uin ~= 0 and self.t_diversionData._v_ ~= mis_config.n_diversionVer then
		self.t_diversionData = {_v_ = mis_config.n_diversionVer, [1] = {}}
	end
	return t_retCode.n_OK, self.t_diversionData[1]
end

--------------------------------------------------------------
-- 说明：设置导流数据
-- 参数：t_data 		数据
-- 返回：n			状态码
--		s 			描述
function this:set_diversion_data(t_data)
	if not self.t_diversionData then
		self.t_diversionData = {_v_ = mis_config.n_diversionVer}
	end
	self.t_diversionData[1] = t_data
	local n_code, s_desc = set_data_to_box(self, mis_config.t_ssdbKey.s_DIVERSION, self.t_diversionData)
	self.t_diversionData._k_ = nil
	self.t_diversionData._t_ = nil
	return n_code, s_desc
end

--------------------------------------------------------------
-- 说明：删除导流数据
-- 返回：n			状态码
--		s 			描述
function this:delete_diversion_data()
	return set_data_to_box(self, mis_config.t_ssdbKey.s_DIVERSION, nil)
end

-- 说明：查询是否有一期回归数据
-- 参数：b_readOnly	是否只读
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:check_back_data_is_have(b_readOnly, b_force)

	local n_code, ts_data = get_data_from_box(self, mis_config.t_ssdbKey.s_BACK, b_readOnly)
	if ts_data and type(ts_data) == 'table' and ts_data._v_ and ts_data[1] and ts_data[1].status and ts_data[1].status ~= 0 then
		--存在回归数据了
 		return true
	end

	return false
end

function this:new_twoback_data()
	return {}
end
--------------------------------------------------------------
-- 说明：获得二期回流数据
-- 参数：b_readOnly	是否只读
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:get_twoback_data(b_readOnly, b_force)
	if not self.t_twobackData or b_force then
		local n_code, ts_data = get_data_from_box(self, mis_config.t_ssdbKey.s_TWOBACK, b_readOnly)
		if n_code == t_retCode.n_NO_DATA then
			ts_data = {_v_ = mis_config.n_twobackVer, [1] = self:new_twoback_data()}
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_data
		end
		self.t_twobackData = ts_data
	end
	-- 如果版本号不一致，清空数据
	if self.n_uin ~= 0 and self.t_twobackData._v_ ~= mis_config.n_twobackVer then
		self.t_twobackData = {_v_ = mis_config.n_twobackVer, [1] = self:new_twoback_data()}
	end
	return t_retCode.n_OK, self.t_twobackData[1]
end

--------------------------------------------------------------
-- 说明：设置二期回流数据
-- 参数：t_data 		数据
-- 返回：n			状态码
--		s 			描述
function this:set_twoback_data(t_data)
	if not self.t_twobackData then
		self.t_twobackData = {_v_ = mis_config.n_twobackVer}
	end
	self.t_twobackData[1] = t_data
	local n_code, s_desc = set_data_to_box(self, mis_config.t_ssdbKey.s_TWOBACK, self.t_twobackData)
	self.t_twobackData._k_ = nil
	self.t_twobackData._t_ = nil
	return n_code, s_desc
end

--------------------------------------------------------------
-- 说明：删除二期回流数据
-- 返回：n			状态码
--		s 			描述
function this:delete_twoback_data()
	return set_data_to_box(self, mis_config.t_ssdbKey.s_TWOBACK, nil)
end

-- 说明：查询是否有二期回归数据
-- 参数：b_readOnly	是否只读
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:check_twoback_data_is_have(b_readOnly, b_force)

	local n_code, ts_data = get_data_from_box(self, mis_config.t_ssdbKey.s_TWOBACK, b_readOnly)
	if ts_data and type(ts_data) == 'table' and ts_data._v_ and ts_data[1] and ts_data[1].old_or_new then
		--存在回归数据了
 		return true
	end

	return false
end

-- 说明：查询是否有二期回归数据 另一种格式去掉old_or_new
-- 参数：b_readOnly	是否只读
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:check_twoback_data_is_have_two(b_readOnly, b_force)

	local n_code, ts_data = get_data_from_box(self, mis_config.t_ssdbKey.s_TWOBACK, b_readOnly)
	if ts_data and type(ts_data) == 'table' and ts_data._v_ then
		--存在回归数据了
 		return true
	end

	return false
end

function this:new_nationalday_data()
	return {}
end
--------------------------------------------------------------
-- 说明：获得国庆活动数据
-- 参数：b_readOnly	是否只读
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:get_nationalday_data(b_readOnly, b_force)
	if not self.t_nationaldayData or b_force then
		local n_code, ts_data = get_data_from_box(self, mis_config.t_ssdbKey.s_NATIONALDAY, b_readOnly)
		if n_code == t_retCode.n_NO_DATA then
			ts_data = {_v_ = mis_config.n_nationaldayVer, [1] = self:new_nationalday_data()}
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_data
		end
		self.t_nationaldayData = ts_data
	end
	-- 如果版本号不一致，清空数据
	if self.n_uin ~= 0 and self.t_nationaldayData._v_ ~= mis_config.n_nationaldayVer then
		self.t_nationaldayData = {_v_ = mis_config.n_nationaldayVer, [1] = self:new_nationalday_data()}
	end
	return t_retCode.n_OK, self.t_nationaldayData[1]
end

--------------------------------------------------------------
-- 说明：设置国庆数据
-- 参数：t_data 		数据
-- 返回：n			状态码
--		s 			描述
function this:set_nationalday_data(t_data)
	if not self.t_nationaldayData then
		self.t_nationaldayData = {_v_ = mis_config.n_nationaldayVer}
	end
	self.t_nationaldayData[1] = t_data
	local n_code, s_desc = set_data_to_box(self, mis_config.t_ssdbKey.s_NATIONALDAY, self.t_nationaldayData)
	self.t_nationaldayData._k_ = nil
	self.t_nationaldayData._t_ = nil
	return n_code, s_desc
end

--------------------------------------------------------------
-- 说明：删除国庆数据
-- 返回：n			状态码
--		s 			描述
function this:delete_nationalday_data()
	return set_data_to_box(self, mis_config.t_ssdbKey.s_NATIONALDAY, nil)
end

--------------------------------------------------------------
-- 说明：获得双旦活动数据
-- 参数：b_readOnly	是否只读
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:get_doubledan_data(b_readOnly, b_force)
	if not self.t_doubledanData or b_force then
		local n_code, ts_data = get_data_from_box(self, mis_config.t_ssdbKey.s_DOUBLEDAN, b_readOnly)
		if n_code == t_retCode.n_NO_DATA then
			ts_data = {_v_ = mis_config.n_doubledanVer, [1] = {}}
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_data
		end
		self.t_doubledanData = ts_data
	end
	-- 如果版本号不一致，清空数据
	if self.n_uin ~= 0 and self.t_doubledanData._v_ ~= mis_config.n_doubledanVer then
		self.t_doubledanData = {_v_ = mis_config.n_doubledanVer, [1] = {}}
	end
	return t_retCode.n_OK, self.t_doubledanData[1]
end

--------------------------------------------------------------
-- 说明：设置国庆数据
-- 参数：t_data 		数据
-- 返回：n			状态码
--		s 			描述
function this:set_doubledan_data(t_data)
	if not self.t_doubledanData then
		self.t_doubledanData = {_v_ = mis_config.n_doubledanVer}
	end
	self.t_doubledanData[1] = t_data
	local n_code, s_desc = set_data_to_box(self, mis_config.t_ssdbKey.s_DOUBLEDAN, self.t_doubledanData)
	--self.t_doubledanData._k_ = nil
	--self.t_doubledanData._t_ = nil
	return n_code, s_desc
end

--------------------------------------------------------------
-- 说明：删除国庆数据
-- 返回：n			状态码
--		s 			描述
function this:delete_doubledan_data()
	return set_data_to_box(self, mis_config.t_ssdbKey.s_DOUBLEDAN, nil)
end

--------------------------------------------------------------
-- 说明：新建成长守护计划数据
-- 返回：n			状态码
--		s 			描述
function this:new_growthguard_data()
	return {}
end

--------------------------------------------------------------
-- 说明：获得成长守护计划数据
-- 参数：b_readOnly	是否只读
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:get_growthguard_data(b_readOnly, b_force)
	if not self.t_growthguardData or b_force then
		local n_code, ts_data = get_data_from_box(self, mis_config.t_ssdbKey.s_GROWTHGUARD, b_readOnly)
		if n_code == t_retCode.n_NO_DATA then
			ts_data = {_v_ = mis_config.n_growthguardVer, [1] = self:new_growthguard_data()}
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_data
		end
		self.t_growthguardData = ts_data
	end
	-- 如果版本号不一致，清空数据
	if self.n_uin ~= 0 and self.t_growthguardData._v_ ~= mis_config.n_growthguardVer then
		self.t_growthguardData = {_v_ = mis_config.n_growthguardVer, [1] = self:new_growthguard_data()}
	end
	return t_retCode.n_OK, self.t_growthguardData[1]
end

--------------------------------------------------------------
-- 说明：设置成长守护计划数据
-- 参数：t_data 		数据
-- 返回：n			状态码
--		s 			描述
function this:set_growthguard_data(t_data)
	if not self.t_growthguardData then
		self.t_growthguardData = {_v_ = mis_config.n_growthguardVer}
	end
	self.t_growthguardData[1] = t_data
	local n_code, s_desc = set_data_to_box(self, mis_config.t_ssdbKey.s_GROWTHGUARD, self.t_growthguardData)
	self.t_growthguardData._k_ = nil
	self.t_growthguardData._t_ = nil
	return n_code, s_desc
end

--------------------------------------------------------------
-- 说明：删除成长守护计划数据
-- 返回：n			状态码
--		s 			描述
function this:delete_growthguard_data()
	return set_data_to_box(self, mis_config.t_ssdbKey.s_GROWTHGUARD, nil)
end

--------------------------------------------------------------
-- 说明：新建周末好礼数据
-- 返回：n			状态码
--		s 			描述
function this:new_weekend_gift_data()
	return {}
end

--------------------------------------------------------------
-- 说明：获得周末好礼数据
-- 参数：b_readOnly	是否只读
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:get_weekend_gift_data(b_readOnly, b_force)
	if not self.t_weekendGiftData or b_force then
		local n_code, ts_data = get_data_from_box(self, mis_config.t_ssdbKey.s_WEEKEND_GIFT, b_readOnly)
		if n_code == t_retCode.n_NO_DATA then
			ts_data = {_v_ = mis_config.n_weedkenGiftVer, [1] = self:new_weekend_gift_data()}
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_data
		end
		self.t_weekendGiftData = ts_data
	end
	-- 如果版本号不一致，清空数据
	if self.n_uin ~= 0 and self.t_weekendGiftData._v_ ~= mis_config.n_weedkenGiftVer then
		self.t_weekendGiftData = {_v_ = mis_config.n_weedkenGiftVer, [1] = self:new_weekend_gift_data()}
	end
	return t_retCode.n_OK, self.t_weekendGiftData[1]
end

--------------------------------------------------------------
-- 说明：设置周末好礼数据
-- 参数：t_data 		数据
-- 返回：n			状态码
--		s 			描述
function this:set_weekend_gift_data(t_data)
	if not self.t_weekendGiftData then
		self.t_weekendGiftData = {_v_ = mis_config.n_weedkenGiftVer}
	end
	self.t_weekendGiftData[1] = t_data
	local n_code, s_desc = set_data_to_box(self, mis_config.t_ssdbKey.s_WEEKEND_GIFT, self.t_weekendGiftData)
	self.t_weekendGiftData._k_ = nil
	self.t_weekendGiftData._t_ = nil
	return n_code, s_desc
end

--------------------------------------------------------------
-- 说明：删除周末好礼数据
-- 返回：n			状态码
--		s 			描述
function this:delete_weekend_gift_data()
	return set_data_to_box(self, mis_config.t_ssdbKey.s_WEEKEND_GIFT, nil)
end

--------------------------------------------------------------
-- 说明：新建国宝复刻数据
-- 返回：n			状态码
--		s 			描述
function this:new_relic_imitate_data()
	return {}
end

--------------------------------------------------------------
-- 说明：获得国宝复刻数据
-- 参数：b_readOnly	是否只读
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:get_relic_imitate_data(b_readOnly, b_force)
	if not self.t_relicImitateData or b_force then
		local n_code, ts_data = get_data_from_box(self, mis_config.t_ssdbKey.s_RELIC_IMITATE, b_readOnly)
		if n_code == t_retCode.n_NO_DATA then
			ts_data = {_v_ = mis_config.n_relicImitateVer, [1] = self:new_relic_imitate_data()}
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_data
		end
		self.t_relicImitateData = ts_data
	end
	-- 如果版本号不一致，清空数据
	if self.n_uin ~= 0 and self.t_relicImitateData._v_ ~= mis_config.n_relicImitateVer then
		self.t_relicImitateData = {_v_ = mis_config.n_relicImitateVer, [1] = self:new_relic_imitate_data()}
	end
	return t_retCode.n_OK, self.t_relicImitateData[1]
end

--------------------------------------------------------------
-- 说明：设置国宝复刻数据
-- 参数：t_data 		数据
-- 返回：n			状态码
--		s 			描述
function this:set_relic_imitate_data(t_data)
	if not self.t_relicImitateData then
		self.t_relicImitateData = {_v_ = mis_config.n_relicImitateVer}
	end
	self.t_relicImitateData[1] = t_data
	local n_code, s_desc = set_data_to_box(self, mis_config.t_ssdbKey.s_RELIC_IMITATE, self.t_relicImitateData)
	self.t_relicImitateData._k_ = nil
	self.t_relicImitateData._t_ = nil
	return n_code, s_desc
end

--------------------------------------------------------------
-- 说明：删除国宝复刻数据
-- 返回：n			状态码
--		s 			描述
function this:delete_relic_imitate_data()
	return set_data_to_box(self, mis_config.t_ssdbKey.s_RELIC_IMITATE, nil)
end

--------------------------------------------------------------
-- 说明：新建国宝复刻地图投票数据
-- 返回：n			状态码
--		s 			描述
function this:new_relic_imitate_map_data()
	return {}
end

--------------------------------------------------------------
-- 说明：获得国宝复刻地图数据
-- 参数：b_readOnly	是否只读
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:get_relic_imitate_map_data(map_id, b_readOnly, b_force)
	if self.n_uin ~= 0 then
		return t_retCode.n_OPER_ERR, 'sys user limit'
	end

	if not ngx.ctx.t_relicImitateMapData then
		ngx.ctx.t_relicImitateMapData = {}
	end

	local s_key = mis_config.t_ssdbKey.s_RELIC_IMITATE_MAP .. map_id
	local t_ret = ngx.ctx.t_relicImitateMapData[s_key]

	if not t_ret or b_force then
		local n_code, ts_data = get_data_from_box(self, s_key, b_readOnly)
		if n_code == t_retCode.n_NO_DATA then
			ts_data = {_v_ = mis_config.n_relicImitateMapVer, [1] = self:new_relic_imitate_map_data()}
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_data
		end
		t_ret = ts_data
		ngx.ctx.t_relicImitateMapData[s_key] = ts_data
		
		-- log.day_list("relic_imitate","get_relic_imitate_map_data","from dc",ngx.ctx.t_params.uin, uu.to_str(ngx.ctx.t_relicImitateMapData))

	else
		log.day_list("relic_imitate","get_relic_imitate_map_data","from cache",ngx.ctx.t_params.uin, uu.to_str(ngx.ctx.t_relicImitateMapData))
	end
	-- 如果版本号不一致，清空数据
	if t_ret._v_ ~= mis_config.n_relicImitateMapVer then
		ngx.ctx.t_relicImitateMapData[s_key] = {_v_ = mis_config.n_relicImitateMapVer, [1] = self:new_relic_imitate_map_data()}
	end
	return t_retCode.n_OK, ngx.ctx.t_relicImitateMapData[s_key][1]
end

--------------------------------------------------------------
-- 说明：批量获得国宝复刻地图数据
-- 返回：n			状态码
--		ts 			描述
function this:get_relic_imitate_map_data_batch(map_list)
	if self.n_uin ~= 0 then
		return t_retCode.n_OPER_ERR, 'sys user limit'
	end

	if not ngx.ctx.t_relicImitateMapData then
		ngx.ctx.t_relicImitateMapData = {}
	end

	local ret = {}
	local kv_list = {}
	for k, v in pairs(map_list) do
		local s_key = mis_config.t_ssdbKey.s_RELIC_IMITATE_MAP .. v
		if ngx.ctx.t_relicImitateMapData[s_key] == nil then
			table_insert(kv_list, {key = self.n_uin, hash = s_key})
		else
			ret[s_key] = ngx.ctx.t_relicImitateMapData[s_key][1]
		end
	end

	if #kv_list > 0 then
		local n_code, ts_data = get_data_from_box_batch(self, kv_list)

		-- log.day_list("relic_imitate","get_relic_imitate_map_data_batch"," ret ",ngx.ctx.t_params.uin, uu.to_str(kv_list), n_code, uu.to_str(ts_data))

		if n_code == t_retCode.n_NO_DATA then
			ts_data = {}
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_data
		end
		for _, v in ipairs(ts_data) do
			-- 如果版本号不一致，清空数据
			if v._v_ ~= mis_config.n_relicImitateMapVer then
				local key, hash = v.__key, v.__hash
				v = {_v_ = mis_config.n_relicImitateMapVer, __hash = hash, __key = key, [1] = self:new_relic_imitate_map_data()}
			end
			if not v.__nil then
				ret[v.__hash] = v[1]
				ngx.ctx.t_relicImitateMapData[v.__hash] = v
			else
				ngx.ctx.t_relicImitateMapData[v.__hash] = nil
			end
		end
	end

	return t_retCode.n_OK, ret
end

--------------------------------------------------------------
-- 说明：设置国宝复刻地图数据
-- 参数：t_data 		数据
-- 返回：n			状态码
--		s 			描述
function this:set_relic_imitate_map_data(map_id, t_data)
	if self.n_uin ~= 0 then
		return t_retCode.n_OPER_ERR, 'sys user limit'
	end

	local s_key = mis_config.t_ssdbKey.s_RELIC_IMITATE_MAP .. map_id
	local t_ret = ngx.ctx.t_relicImitateMapData[s_key]

	if not ngx.ctx.t_relicImitateMapData then
		ngx.ctx.t_relicImitateMapData = {}
	end

	if not ngx.ctx.t_relicImitateMapData[s_key] then
		ngx.ctx.t_relicImitateMapData[s_key] = {_v_ = mis_config.n_relicImitateMapVer}
	end
	ngx.ctx.t_relicImitateMapData[s_key][1] = t_data

	local n_code, s_desc = set_data_to_box(self, s_key, ngx.ctx.t_relicImitateMapData[s_key])
	ngx.ctx.t_relicImitateMapData[s_key]._k_ = nil
	ngx.ctx.t_relicImitateMapData[s_key]._t_ = nil

	return n_code, s_desc
end


-- 返回：t			音乐嘉年华数据
function this:new_concert_data()
	return {}
end

--------------------------------------------------------------
-- 说明：获得音乐嘉年华数据
-- 参数：b_readOnly	是否只读
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:get_concert_data(b_readOnly, b_force)
	if not self.t_concertData or b_force then
		local n_code, ts_data = get_data_from_box(self, mis_config.t_ssdbKey.s_CONCERT, b_readOnly)
		if n_code == t_retCode.n_NO_DATA then
			ts_data = {_v_ = mis_config.n_concertVer, [1] = self:new_concert_data()}
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_data
		end
		self.t_concertData = ts_data
	end
	-- 如果版本号不一致，清空数据
	if self.n_uin ~= 0 and self.t_concertData._v_ ~= mis_config.n_concertVer then
		self.t_concertData = {_v_ = mis_config.n_concertVer, [1] = self:new_concert_data()}
	end
	return t_retCode.n_OK, self.t_concertData[1]
end

--------------------------------------------------------------
-- 说明：设置音乐嘉年华数据
-- 参数：t_data 		数据
-- 参数：t_data2 	数据
-- 返回：n			状态码
--		s 			描述
function this:set_concert_data(t_data)
	if not self.t_concertData then
		self.t_concertData = {_v_ = mis_config.n_concertVer}
	end
	self.t_concertData[1] = t_data
	local n_code, s_desc = set_data_to_box(self, mis_config.t_ssdbKey.s_CONCERT, self.t_concertData)
	self.t_concertData._k_ = nil
	self.t_concertData._t_ = nil
	return n_code, s_desc
end

--------------------------------------------------------------
-- 说明：删除音乐嘉年华数据
-- 返回：n			状态码
--		s 			描述
function this:delete_concert_data()
	return set_data_to_box(self, mis_config.t_ssdbKey.s_CONCERT, nil)
end

-- 返回：t			音乐嘉年华音乐密码数据
function this:new_concert_code_data()
	return {}
end

--------------------------------------------------------------
-- 说明：获得音乐嘉年华音乐密码数据
-- 参数：b_readOnly	是否只读
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:get_concert_code_data(s_code, b_readOnly, b_force)
	if self.n_uin ~= 0 then
		return t_retCode.n_OPER_ERR, 'sys user limit'
	end

	if not ngx.ctx.t_concertCodeData then
		ngx.ctx.t_concertCodeData = {}
	end

	local s_key = mis_config.t_ssdbKey.s_CONCERT_CODE .. s_code
	local t_ret = ngx.ctx.t_concertCodeData[s_key]

	if not t_ret or b_force then
		local n_hash = mis_calcu.concert_code_hash(s_code)
		local n_code, ts_data = get_data_from_box_hash(self, n_hash, s_key, b_readOnly)
		if n_code == t_retCode.n_NO_DATA then
			ts_data = {_v_ = mis_config.n_concertCodeVer, [1] = self:new_concert_code_data()}
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_data
		end
		t_ret = ts_data
		ngx.ctx.t_concertCodeData[s_key] = ts_data
		
		log.day_list("concert_code","get_concert_code_data","from dc",ngx.ctx.t_params.uin, uu.to_str(ngx.ctx.t_concertCodeData))

	else
		log.day_list("concert_code","get_concert_code_data","from cache",ngx.ctx.t_params.uin, uu.to_str(ngx.ctx.t_concertCodeData))
	end
	-- 如果版本号不一致，清空数据
	if t_ret._v_ ~= mis_config.n_concertCodeVer then
		ngx.ctx.t_concertCodeData[s_key] = {_v_ = mis_config.n_concertCodeVer, [1] = self:new_concert_code_data()}
	end
	return t_retCode.n_OK, ngx.ctx.t_concertCodeData[s_key][1]
end

--------------------------------------------------------------
-- 说明：设置音乐嘉年华音乐密码数据
-- 参数：t_data 		数据
-- 参数：t_data2 	数据
-- 返回：n			状态码
--		s 			描述
function this:set_concert_code_data(s_code, t_data)
	if self.n_uin ~= 0 then
		return t_retCode.n_OPER_ERR, 'sys user limit'
	end

	local s_key = mis_config.t_ssdbKey.s_CONCERT_CODE .. s_code

	if not ngx.ctx.t_concertCodeData then
		ngx.ctx.t_concertCodeData = {}
	end

	if not ngx.ctx.t_concertCodeData[s_key] then
		ngx.ctx.t_concertCodeData[s_key] = {_v_ = mis_config.n_concertCodeVer}
	end
	ngx.ctx.t_concertCodeData[s_key][1] = t_data
	
	-- log.day_list("concert" ,"set_concert_code_data", "ok", uu.to_str(s_code), uu.to_str(t_data), tostring(mis_calcu.concert_code_hash))

	local n_hash = mis_calcu.concert_code_hash(s_code)
	local n_code, s_desc = set_data_to_box_hash(self, n_hash, s_key, ngx.ctx.t_concertCodeData[s_key])
	ngx.ctx.t_concertCodeData[s_key]._k_ = nil
	ngx.ctx.t_concertCodeData[s_key]._t_ = nil

	return n_code, s_desc
end

-- 返回：t	分享密码数据
function this:new_share_code_data()
	return {}
end

--------------------------------------------------------------
-- 说明：获得分享密码数据
-- 参数：b_readOnly	是否只读
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:get_share_code_data(s_type, s_code, b_readOnly, b_force)
	if self.n_uin ~= 0 then
		return t_retCode.n_OPER_ERR, 'sys user limit'
	end

	-- 分享码缓存
	ngx.ctx.t_shareCodeData2 = ngx.ctx.t_shareCodeData2 or {}

	local s_key = mis_config.t_sharessdbKeyMap[s_type]
	local n_ver = mis_config.t_versionMap[s_type]

	s_key = s_key .. s_type .. s_code
	local t_ret = ngx.ctx.t_shareCodeData2[s_key]

	if not t_ret or b_force then
		local n_hash = mis_calcu.share_code_hash(s_code)
		local n_code, ts_data = get_data_from_box_hash(self, n_hash, s_key, b_readOnly, s_type)
		if n_code == t_retCode.n_NO_DATA then
			ts_data = {_v_ = n_ver, [1] = self:new_share_code_data()}
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_data
		end
		t_ret = ts_data
		ngx.ctx.t_shareCodeData2[s_key] = ts_data
		
		-- log.day_list("share_code","get_share_code_data", "from dc", s_type,ngx.ctx.t_params.uin, uu.to_str(ts_data))

	else
		log.day_list("share_code","get_share_code_data", "from cache", s_type,ngx.ctx.t_params.uin)
	end
	-- 如果版本号不一致，清空数据
	if t_ret._v_ ~= n_ver then
		ngx.ctx.t_shareCodeData2[s_key] = {_v_ = n_ver, [1] = self:new_share_code_data()}
	end
	return t_retCode.n_OK, ngx.ctx.t_shareCodeData2[s_key][1]
end

--------------------------------------------------------------
-- 说明：设置分享密码数据
-- 参数：t_data 		数据
-- 参数：t_data2 	数据
-- 返回：n			状态码
--		s 			描述
function this:set_share_code_data(s_type, s_code, t_data)
	if self.n_uin ~= 0 then
		return t_retCode.n_OPER_ERR, 'sys user limit'
	end

	-- 分享码缓存
	ngx.ctx.t_shareCodeData2 = ngx.ctx.t_shareCodeData2 or {}

	local s_key = mis_config.t_sharessdbKeyMap[s_type]
	local n_ver = mis_config.t_versionMap[s_type]

	s_key = s_key .. s_type .. s_code
	local t_ret = ngx.ctx.t_shareCodeData2[s_key]

	if not ngx.ctx.t_shareCodeData2[s_key] then
		ngx.ctx.t_shareCodeData2[s_key] = {_v_ = n_ver}
	end
	ngx.ctx.t_shareCodeData2[s_key][1] = t_data
	
	local n_hash = mis_calcu.share_code_hash(s_code)
	local n_code, s_desc = set_data_to_box_hash(self, n_hash, s_key, ngx.ctx.t_shareCodeData2[s_key], s_type)
	ngx.ctx.t_shareCodeData2[s_key]._k_ = nil
	ngx.ctx.t_shareCodeData2[s_key]._t_ = nil

	return n_code, s_desc
end

--------------------------------------------------------------
-- 说明：虚拟加锁-分享密码数据
-- 参数：t_data 		数据
-- 参数：t_data2 	数据
-- 返回：n			状态码
--		s 			描述
function this:add_share_code_read_lock(s_type, s_code)
	if self.n_uin ~= 0 then
		return t_retCode.n_OPER_ERR, 'sys user limit'
	end
	
	local s_key = mis_config.t_sharessdbKeyMap[s_type]
	s_key = s_key .. s_type .. s_code
	local n_hash = mis_calcu.share_code_hash(s_code)
	this.add_read_lock_hash(self, s_key, n_hash, s_type)

	return t_retCode.n_OK
end

-- 虚拟加锁，避免ssdb error_not_find_lock 错误
function this:add_read_lock( s_key )
	-- hash_ = mis_config.t_ssdbKey.s_USER
	self.t_ssdb:add_read_lock( self.n_uin % #mis_config.t_ssdbDc.t_select, self.n_uin, s_key );
end

-- 虚拟加锁，避免ssdb error_not_find_lock 错误
function this:add_read_lock_hash( s_key, n_hash, s_work )
	-- hash_ = mis_config.t_ssdbKey.s_USER
	local n_dbIndex = n_hash % #mis_config.t_ssdbDc.t_select
	local s_workKey = self.n_uin
	if s_work then
		s_workKey = s_workKey .. "_" .. s_work
	end
	self.t_ssdb:add_read_lock( n_dbIndex, s_workKey, s_key );
end

function this:check_twoback_or_oneback()

	local t_backConf = mis_data.t_back.t_conf
		local code_w, t_backData = self:get_back_data(true)

		if code_w ~= t_retCode.n_OK then
			return false
		end
		local n_now = uu.now()
		if  t_backConf and t_backData and t_backData.startTime then
			--判断一期
			if t_backConf.n_showTime and t_backConf.n_showTime <= n_now - t_backData.startTime then
				
				log.day_list("twoback","pre_twoback-flag-11",ngx.ctx.t_params.uin,t_backData.startTime)
				return true

			else
				if t_backConf.n_missionTime and t_backConf.n_missionTime <= n_now - t_backData.startTime then
					--过了任务时间，看身上是否还有积分可换
					if t_backData.score and t_backData.totalScore then
						if t_backData.score > 0 or t_backData.totalScore > 0 then
							log.day_list("twoback","pre_twoback-flag-12",ngx.ctx.t_params.uin,t_backData.score,t_backData.totalScore)
						else
							log.day_list("twoback","pre_twoback-flag-13",ngx.ctx.t_params.uin,t_backData.startTime)
							return true
							
						end
					end
				end

			end


		else
			--判断二期
			local longconf 	= mis_data.t_twoback.t_conf_long
			local shortconf = mis_data.t_twoback.t_conf_short
			local code_q, desc_q = self:get_user_basic()
			local te_time = 0
			if code_q == t_retCode.n_OK then
				te_time = tonumber(desc_q.last_login_time) or 0
			end

			if te_time ~= 0 and longconf and shortconf then
				local day_q = math_floor((n_now - te_time)/86400)
				if day_q >= longconf.lost_day or day_q >= shortconf.lost_day then
					
					log.day_list("twoback","pre_twoback-flag-14",ngx.ctx.t_params.uin,day_q)
					return true
				end
			end

		end


		return false
end

-- 返回：新建业务数据
function this:new_work_data(s_workType)
	return {}
end

--------------------------------------------------------------
-- 说明：获取业务数据
-- 参数：b_readOnly	是否只读
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:get_work_data(s_workType, s_ssdbKey, b_readOnly, b_force)
	local t_workData = self.t_workData or {}
	local n_workVer = mis_config.t_workVer[s_workType]
	if not t_workData[s_workType] or b_force then
		local n_code, ts_data = get_data_from_box(self, s_workType, b_readOnly)
		if n_code == t_retCode.n_NO_DATA then
			ts_data = {_v_ = n_workVer, [1] = self:new_work_data(s_workType)}
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_data
		end
		t_workData[s_workType] = ts_data
	end
	-- 如果版本号不一致，清空数据
	if self.n_uin ~= 0 and t_workData[s_workType]._v_ ~= n_workVer then
		t_workData[s_workType] = {_v_ = n_workVer, [1] = self:new_work_data(s_workType)}
	end
	self.t_workData = t_workData
	return t_retCode.n_OK, t_workData[s_workType][1]
end

--------------------------------------------------------------
-- 说明：设置业务数据
-- 参数：t_data 		数据
-- 参数：t_data2 	数据
-- 返回：n			状态码
--		s 			描述
function this:set_work_data(s_workType, s_ssdbKey, t_data)
	local t_workData = self.t_workData or {}
	local n_workVer = mis_config.t_workVer[s_workType]
	if not t_workData[s_workType] then
		t_workData[s_workType] = {_v_ = n_workVer}
	end
	t_workData[s_workType][1] = t_data
	local n_code, s_desc = set_data_to_box(self, s_ssdbKey, t_workData[s_workType])
	t_workData[s_workType]._k_ = nil
	t_workData[s_workType]._t_ = nil
	self.t_workData = t_workData
	return n_code, s_desc
end

--------------------------------------------------------------
-- 说明：删除业务数据
-- 返回：n			状态码
--		s 			描述
function this:delete_work_data(s_workType, s_ssdbKey)
	if self.t_workData and self.t_workData[s_workType] then
		self.t_workData[s_workType] = nil
	end
	return set_data_to_box(self, s_ssdbKey, nil)
end


-- 返回：t	每日签到数据
function this:new_daily_sign_data()
	return {}
end

--------------------------------------------------------------
-- 说明：获得每日签到数据
-- 参数：b_readOnly	是否只读
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:get_daily_sign_data(b_readOnly, b_force)
	if not self.t_dailySignData or b_force then
		local n_code, ts_data = get_data_from_box(self, mis_config.t_ssdbKey.s_DAILY_SIGN, b_readOnly)
		if n_code == t_retCode.n_NO_DATA then
			ts_data = {_v_ = mis_config.n_dailySignVer, [1] = self:new_daily_sign_data()}
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_data
		end
		self.t_dailySignData = ts_data
	end
	-- 如果版本号不一致，清空数据
	if self.n_uin ~= 0 and self.t_dailySignData._v_ ~= mis_config.n_dailySignVer then
		self.t_dailySignData = {_v_ = mis_config.n_dailySignVer, [1] = self:new_daily_sign_data()}
	end
	return t_retCode.n_OK, self.t_dailySignData[1]
end

--------------------------------------------------------------
-- 说明：设置每日签到数据
-- 参数：t_data 		数据
-- 参数：t_data2 	数据
-- 返回：n			状态码
--		s 			描述
function this:set_daily_sign_data(t_data)
	if not self.t_dailySignData then
		self.t_dailySignData = {_v_ = mis_config.n_dailySignVer}
	end
	self.t_dailySignData[1] = t_data
	local n_code, s_desc = set_data_to_box(self, mis_config.t_ssdbKey.s_DAILY_SIGN, self.t_dailySignData)
	self.t_dailySignData._k_ = nil
	self.t_dailySignData._t_ = nil
	return n_code, s_desc
end

--------------------------------------------------------------
-- 说明：删除每日签到数据
-- 返回：n			状态码
--		s 			描述
function this:delete_daily_sign_data()
	return set_data_to_box(self, mis_config.t_ssdbKey.s_DAILY_SIGN, nil)
end


-- 返回：t	新手任务数据
function this:new_novice_task_data()
	return {}
end

--------------------------------------------------------------
-- 说明：获得新手任务数据
-- 参数：b_readOnly	是否只读
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:get_novice_task_data(b_readOnly, b_force)
	if not self.t_noviceTaskData or b_force then
		local n_code, ts_data = get_data_from_box(self, mis_config.t_ssdbKey.s_NOVICE_TASK, b_readOnly)
		if n_code == t_retCode.n_NO_DATA then
			ts_data = {_v_ = mis_config.n_noviceTaskVer, [1] = self:new_novice_task_data()}
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_data
		end
		self.t_noviceTaskData = ts_data
	end
	-- 如果版本号不一致，清空数据
	if self.n_uin ~= 0 and self.t_noviceTaskData._v_ ~= mis_config.n_noviceTaskVer then
		self.t_noviceTaskData = {_v_ = mis_config.n_noviceTaskVer, [1] = self:new_novice_task_data()}
	end
	return t_retCode.n_OK, self.t_noviceTaskData[1]
end

--------------------------------------------------------------
-- 说明：设置新手任务数据
-- 参数：t_data 		数据
-- 参数：t_data2 	数据
-- 返回：n			状态码
--		s 			描述
function this:set_novice_task_data(t_data)
	if not self.t_noviceTaskData then
		self.t_noviceTaskData = {_v_ = mis_config.n_noviceTaskVer}
	end
	self.t_noviceTaskData[1] = t_data
	local n_code, s_desc = set_data_to_box(self, mis_config.t_ssdbKey.s_NOVICE_TASK, self.t_noviceTaskData)
	self.t_noviceTaskData._k_ = nil
	self.t_noviceTaskData._t_ = nil
	return n_code, s_desc
end

--------------------------------------------------------------
-- 说明：删除新手任务数据
-- 返回：n			状态码
--		s 			描述
function this:delete_novice_task_data()
	return set_data_to_box(self, mis_config.t_ssdbKey.s_NOVICE_TASK, nil)
end

-- 返回：t			任务数据（共享任务）
function this:new_share_mission_data()
	return {}
end

--------------------------------------------------------------
-- 说明：获得觉醒活动数据（跟共享任务公用数据）
-- 参数：b_readOnly	是否只读
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:get_awakening_activity_data(b_readOnly, b_force)
	local s_key = mis_config.t_ssdbKey.s_AWAKENING_ACTIVITY
	local n_ver = mis_config.n_awakeningVer
	self.t_shareMissionData = self.t_shareMissionData or {}

	if not self.t_shareMissionData[s_key] or b_force then
		local n_code, ts_data = get_data_from_box(self, s_key, b_readOnly)
		if n_code == t_retCode.n_NO_DATA then
			ts_data = {_v_ = n_ver, [1] = self:new_share_mission_data()}
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_data
		end
		self.t_shareMissionData[s_key] = ts_data
	end
	-- 如果版本号不一致，清空数据
	if self.n_uin ~= 0 and self.t_shareMissionData[s_key]._v_ ~= n_ver then
		self.t_shareMissionData[s_key] = {_v_ = n_ver, [1] = self:new_share_mission_data()}
	end
	return t_retCode.n_OK, self.t_shareMissionData[s_key][1]
end

--------------------------------------------------------------
-- 说明：设置觉醒活动数据（跟共享任务公用数据）
-- 参数：t_data 		数据
-- 参数：t_data2 	数据
-- 返回：n			状态码
--		s 			描述
function this:set_awakening_activity_data(t_data)
	local s_key = mis_config.t_ssdbKey.s_AWAKENING_ACTIVITY
	local n_ver = mis_config.n_awakeningVer
	self.t_shareMissionData = self.t_shareMissionData or {}

	if not self.t_shareMissionData[s_key] then
		self.t_shareMissionData[s_key] = {_v_ = n_ver}
	end
	self.t_shareMissionData[s_key][1] = t_data
	local n_code, s_desc = set_data_to_box(self, s_key, self.t_shareMissionData[s_key])
	self.t_shareMissionData[s_key]._k_ = nil
	self.t_shareMissionData[s_key]._t_ = nil
	return n_code, s_desc
end

-- 说明：获得任务数据（共享任务）
-- 参数：b_readOnly	是否只读
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:get_share_mission_data(s_type, b_readOnly, b_force)
	local s_key = mis_config.t_sharessdbKeyMap[s_type]
	local n_ver = mis_config.t_versionMap[s_type]
	self.t_shareMissionData = self.t_shareMissionData or {}

	if not (s_key and n_ver) then
		mis_log.error(string_format("work [%s] define error: key %s, ver %s", tostring(s_type), tostring(s_key), tostring(n_ver)))
		return t_retCode.n_WORK_ERR, "work type define error"
	end
	if not self.t_shareMissionData[s_key] or b_force then
		local n_code, ts_data = get_data_from_box(self, s_key, b_readOnly)
		if n_code == t_retCode.n_NO_DATA then
			ts_data = {_v_ = n_ver, [1] = self:new_share_mission_data()}
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_data
		end
		self.t_shareMissionData[s_key] = ts_data
	end
	-- 如果版本号不一致，清空数据
	if self.n_uin ~= 0 and self.t_shareMissionData[s_key]._v_ ~= n_ver then
		self.t_shareMissionData[s_key] = {_v_ = n_ver, [1] = self:new_share_mission_data()}
	end
	return t_retCode.n_OK, self.t_shareMissionData[s_key][1]
end

--------------------------------------------------------------
-- 说明：设置任务数据（共享任务）
-- 参数：t_data 		数据
-- 参数：t_data2 	数据
-- 返回：n			状态码
--		s 			描述
function this:set_share_mission_data(s_type, t_data)
	local s_key = mis_config.t_sharessdbKeyMap[s_type]
	local n_ver = mis_config.t_versionMap[s_type]
	self.t_shareMissionData = self.t_shareMissionData or {}

	if not (s_key and n_ver) then
		return t_retCode.n_WORK_ERR
	end

	if not self.t_shareMissionData[s_key] then
		self.t_shareMissionData[s_key] = {_v_ = n_ver}
	end
	self.t_shareMissionData[s_key][1] = t_data
	local n_code, s_desc = set_data_to_box(self, s_key, self.t_shareMissionData[s_key])
	self.t_shareMissionData[s_key]._k_ = nil
	self.t_shareMissionData[s_key]._t_ = nil
	return n_code, s_desc
end

--------------------------------------------------------------
-- 说明：删除任务数据（共享任务）
-- 返回：n			状态码
--		s 			描述
function this:delete_share_mission_data(s_type)
	local s_key = mis_config.t_sharessdbKeyMap[s_type]

	if not s_key then
		return t_retCode.n_WORK_ERR
	end

	return set_data_to_box(self, s_key, nil)
end

-- 返回：t			迎财神系统数据
function this:new_wealth_god_data()
	return {}
end

--------------------------------------------------------------
-- 说明：获得迎财神系统数据数据
-- 参数：b_readOnly	是否只读
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:get_wealth_god_data(b_readOnly, b_force)
	if self.n_uin ~= 0 then
		return t_retCode.n_OPER_ERR, 'sys user limit'
	end
	--mis27wealth_god
	local s_key = mis_config.t_ssdbKey.s_CHINESE_YEAR..'wealth_god'
	local n_ver = mis_config.t_versionMap['wealth_god']
	self.t_shareMissionData_wealth_god = {}

	if not (s_key and n_ver) then
		return t_retCode.n_WORK_ERR, 's_key n_ver is nil'
	end

	local hash_flag = ngx.ctx.t_params.uin % #mis_config.t_ssdbDc.t_select

	if mis_config.n_debug == 1 then
		hash_flag = 0
	end

	if not self.t_shareMissionData_wealth_god[s_key] or b_force then
		local n_code, ts_data = get_data_from_box_hash(self, hash_flag, s_key, b_readOnly)
		if n_code == t_retCode.n_NO_DATA then
			ts_data = {_v_ = n_ver, [1] = self:new_wealth_god_data()}
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_data
		end
		self.t_shareMissionData_wealth_god[s_key] = ts_data
	end
	
	return t_retCode.n_OK, self.t_shareMissionData_wealth_god[s_key][1]
end

--------------------------------------------------------------
-- 说明：设置迎财神系统数据数据
-- 参数：t_data 		数据
-- 参数：t_data2 	数据
-- 返回：n			状态码
--		s 			描述
function this:set_wealth_god_data(t_data)
	if self.n_uin ~= 0 then
		return t_retCode.n_OPER_ERR, 'sys user limit'
	end

	local s_key = mis_config.t_ssdbKey.s_CHINESE_YEAR..'wealth_god'
	local n_ver = mis_config.t_versionMap['wealth_god']
	self.t_shareMissionData_wealth_god = self.t_shareMissionData_wealth_god or {}

	if not (s_key and n_ver) then
		return t_retCode.n_WORK_ERR, 's_key n_ver is nil'
	end

	if not self.t_shareMissionData_wealth_god[s_key] then
		self.t_shareMissionData_wealth_god[s_key] = {_v_ = n_ver}
	end
	self.t_shareMissionData_wealth_god[s_key][1] = t_data

	local hash_flag = ngx.ctx.t_params.uin % #mis_config.t_ssdbDc.t_select
	if mis_config.n_debug == 1 then
		hash_flag = 0
	end
	local n_code, s_desc = set_data_to_box_hash(self, hash_flag,s_key, self.t_shareMissionData_wealth_god[s_key])
	self.t_shareMissionData_wealth_god[s_key]._k_ = nil
	self.t_shareMissionData_wealth_god[s_key]._t_ = nil
	return n_code, s_desc

end

--迎财神助力码数据
function this:new_wealth_god_code_data()
	return {}
end

--------------------------------------------------------------
-- 说明：获得迎财神助力码数据
-- 参数：b_readOnly	是否只读
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:get_wealth_god_code_data(s_code, b_readOnly, b_force)
	if self.n_uin ~= 0 then
		return t_retCode.n_OPER_ERR, 'sys user limit'
	end

	local s_key = mis_config.t_ssdbKey.s_CHINESE_YEAR..'wealth_god_code'..s_code
	local n_ver = mis_config.t_versionMap['wealth_god']
	self.code_data = {}

	if not (s_key and n_ver) then
		return t_retCode.n_WORK_ERR, 's_key n_ver is nil'
	end

	local hash_flag = mis_calcu.wealth_god_code_hash(s_code)

	if not self.code_data[s_key] or b_force then
		local n_code, ts_data = get_data_from_box_hash(self, hash_flag, s_key, b_readOnly)
		if n_code == t_retCode.n_NO_DATA then
			ts_data = {_v_ = n_ver, [1] = self:new_wealth_god_code_data()}
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_data
		end
		self.code_data[s_key] = ts_data
	end
	
	return t_retCode.n_OK, self.code_data[s_key][1]
end

--------------------------------------------------------------
-- 说明：设置迎财神密码数据
-- 参数：t_data 		数据
-- 参数：t_data2 	数据
-- 返回：n			状态码
--		s 			描述
function this:set_wealth_god_code_data(s_code, t_data)
	if self.n_uin ~= 0 then
		return t_retCode.n_OPER_ERR, 'sys user limit'
	end

	local s_key = mis_config.t_ssdbKey.s_CHINESE_YEAR..'wealth_god_code'..s_code
	local n_ver = mis_config.t_versionMap['wealth_god']
	self.code_data = self.code_data or {}

	if not (s_key and n_ver) then
		return t_retCode.n_WORK_ERR, 's_key n_ver is nil'
	end

	if not self.code_data[s_key] then
		self.code_data[s_key] = {_v_ = n_ver}
	end
	self.code_data[s_key][1] = t_data

	local hash_flag = mis_calcu.wealth_god_code_hash(s_code)
	local n_code, s_desc = set_data_to_box_hash(self, hash_flag,s_key, self.code_data[s_key])
	self.code_data[s_key]._k_ = nil
	self.code_data[s_key]._t_ = nil
	return n_code, s_desc
end

--拉下新手任务数据看看
function this:get_novice_fuck_data()
	local n_code, ts_data = get_data_from_box(self, mis_config.t_ssdbKey.s_NOVICE_TASK, true)
	return n_code,ts_data
end

--==============================================三丽鸥迷你梦幻岛=======================================
function this:get_sanrio_data(b_readOnly)
	local n_code, ts_data = get_data_from_box(self, mis_config.t_ssdbKey.s_SANRIO, b_readOnly)
	if n_code == t_retCode.n_NO_DATA then
		return t_retCode.n_OK, nil
	elseif n_code ~= t_retCode.n_OK then
		return n_code, ts_data
	end

	return t_retCode.n_OK, ts_data
end

function this:set_sanrio_data(t_data)
	local n_code, s_desc = set_data_to_box(self, mis_config.t_ssdbKey.s_SANRIO, t_data)
	return n_code, s_desc
end

local function set_hash_data(self, n_hash, s_key, t_data, s_work, read_only_ )
	mis_qps.mark('dc')
	local n_dbIndex = n_hash % #mis_config.t_ssdbDc.t_select
	local s_workKey = self.n_uin
	if s_work then
		s_workKey = s_work
	end
	if t_data ~= nil then
		if self.t_ssdb:private_check_set_key(n_dbIndex, s_workKey, s_key, t_data) then
			local s_data = mis_common.table_to_string(t_data)
			local s_ret = self.t_ssdb:save(n_dbIndex, s_workKey, s_key, s_data, nil, nil, read_only_)
			if not s_ret then
				local s_err = 'ssdb save error'
				mis_log.error(s_err)
				return t_retCode.n_DB_ERR, s_err
			end
		else
			local s_err = 'ssdb check key failed'
			mis_log.error(s_err)
			return t_retCode.n_DB_ERR, s_err
		end
	else
		-- 删除
		local s_ret = self.t_ssdb:del(n_dbIndex, s_workKey, s_key)
		if not s_ret then
			local s_err = 'ssdb del error'
			mis_log.error(s_err)
			return t_retCode.n_DB_ERR, s_err
		end
	end
	return t_retCode.n_OK
end

local function get_hash_data(self, n_hash, s_key, s_work, b_readOnly)
	mis_qps.mark('dc')
	local n_dbIndex = n_hash % #mis_config.t_ssdbDc.t_select
	local s_workKey = self.n_uin
	if s_work then
		s_workKey = s_work
	end
	local s_data = self.t_ssdb:read(n_dbIndex, s_workKey, s_key, nil, nil, b_readOnly and 1 or nil)
	if not s_data then
		local s_err = 'ssdb error'
		mis_log.error(s_err)
		return t_retCode.n_DB_ERR, s_err
	elseif s_data == ngx.null then
		return t_retCode.n_NO_DATA, 'no data'
	else
		local t_data = mis_common.string_to_table(s_data)
		if type(t_data) == 'table' then
			if not self.t_ssdb:private_check_get_key(n_dbIndex, s_workKey, s_key, t_data) then
				self.t_ssdb:clean_shared_cache_ssdb(n_dbIndex, s_workKey, s_key)
				local s_err = 'user ssdb data has been damaged 1, uin=' .. self.n_uin .. ', key=' .. s_key .. ", work=" .. uu.to_str(s_workKey)
				mis_log.error(s_err)
				return t_retCode.n_DB_ERR, s_err
			end
		else
			local code, err = self.t_ssdb:clean_shared_cache_ssdb(n_dbIndex, s_workKey, s_key)
			local s_err = 'user ssdb data has been damaged 2, uin=' .. self.n_uin .. ', key=' .. s_key .. ", work=" .. uu.to_str(s_workKey) .. ", data=" .. s_data .. ", code=" .. uu.to_str(code) .. ", err=" .. uu.to_str(err)
			mis_log.error(s_err)
			return t_retCode.n_DB_ERR, s_err
		end
		return t_retCode.n_OK, t_data
	end
end

function this:set_secret_code(key, t_data, read_only_)
	local hash = mis_calcu.share_code_hash(key)
	local n_code, s_desc = set_hash_data(self, hash, key, t_data, "secret_code", read_only_)
	return n_code, s_desc
end

function this:get_secret_code(key)
	local hash = mis_calcu.share_code_hash(key)
	if not hash then 
		return t_retCode.n_DB_ERR, "get_secret_code error"
	end

	local n_code, s_desc = get_hash_data(self, hash, key, "secret_code")
	return n_code, s_desc
end


--新建中秋数据
function this:new_moon_data()
	return {}
end
--------------------------------------------------------------
-- 说明：获得中秋活动数据
-- 参数：b_readOnly	是否只读
--		b_force		是否击穿协程缓存
-- 返回：n			状态码
--		ts 			描述
function this:get_moon_data(b_readOnly, b_force)
	if not self.t_moonData or b_force then
		local n_code, ts_data = get_data_from_box(self, mis_config.t_ssdbKey.s_MOON, b_readOnly)
		if n_code == t_retCode.n_NO_DATA then
			ts_data = {_v_ = mis_config.n_moonVer, [1] = self:new_moon_data()}
		elseif n_code ~= t_retCode.n_OK then
			return n_code, ts_data
		end
		self.t_moonData = ts_data
	end
	-- 如果版本号不一致，清空数据
	if self.n_uin ~= 0 and self.t_moonData._v_ ~= mis_config.n_moonVer then
		self.t_moonData = {_v_ = mis_config.n_moonVer, [1] = self:new_moon_data()}
	end
	return t_retCode.n_OK, self.t_moonData[1]
end

--------------------------------------------------------------
-- 说明：设置中秋数据
-- 参数：t_data 		数据
-- 返回：n			状态码
--		s 			描述
function this:set_moon_data(t_data)
	if not self.t_moonData then
		self.t_moonData = {_v_ = mis_config.n_moonVer}
	end
	self.t_moonData[1] = t_data
	local n_code, s_desc = set_data_to_box(self, mis_config.t_ssdbKey.s_MOON, self.t_moonData)
	self.t_moonData._k_ = nil
	self.t_moonData._t_ = nil
	return n_code, s_desc
end

--==============================================2022国庆活动=======================================
function this:get_national_data(b_readOnly)
	local n_code, ts_data = get_data_from_box(self, mis_config.t_ssdbKey.s_NATIONAL, b_readOnly)
	if n_code == t_retCode.n_NO_DATA then
		return t_retCode.n_OK, nil
	elseif n_code ~= t_retCode.n_OK then
		return n_code, ts_data
	end

	return t_retCode.n_OK, ts_data
end

function this:set_national_data(t_data)
	local n_code, s_desc = set_data_to_box(self, mis_config.t_ssdbKey.s_NATIONAL, t_data)
	return n_code, s_desc
end

--==============================================2022国庆活动=======================================
function this:get_currency_data(b_readOnly)
	local n_code, ts_data = get_data_from_box(self, mis_config.t_ssdbKey.s_CURRENCY, b_readOnly)
	if n_code == t_retCode.n_NO_DATA then
		return t_retCode.n_OK, nil
	elseif n_code ~= t_retCode.n_OK then
		return n_code, ts_data
	end

	return t_retCode.n_OK, ts_data
end
function this:set_currency_data(t_data)
	local n_code, s_desc = set_data_to_box(self, mis_config.t_ssdbKey.s_CURRENCY, t_data)
	return n_code, s_desc
end

return this